//接口初探
interface LabelledValue {
    label: string;
}

function printLabel(labelledObj: LabelledValue) {
    console.log(labelledObj.label);
}

let myObj = { size: 10, label: "Size 10 object" };
printLabel(myObj);

//可选属性
interface SquareConfig {
    color?: string;
    width?: number;
}
function createSquare(config: SquareConfig): { color: string; area: number } {
    let newSquare = { color: "white", area: 100 };
    if (config.color) {
        newSquare.color = config.color;
    }
    if (config.width) {
        newSquare.area = config.width * config.width;
    }
    return newSquare;
}

//只读属性
interface Point {
    readonly x: number;
    readonly y: number;
}

let p1: Point = { x: 10, y: 20 };
//p1.x = 5; //error
//只读属性只能在对象刚刚创建的时候修改其值
let i_a: number[] = [1, 2, 3, 4];
let i_ro: ReadonlyArray<number> = i_a;
//i_ro[0] = 12; //error
//i_ro.push(5); //error
//i_ro.length = 100; //error
//i_a = i_ro; //error
//i_a = i_ro as number[]; //ok

//函数类型
interface SearchFunc {
    (source: string, subString: string): boolean;
}
let mySearch: SearchFunc;
mySearch = function (src, sub) {
    let result = src.search(sub);
    return result > -1;
};

//可索引类型
interface StringArray {
    [index: number]: string; //索引签名
}
let myArray: StringArray;
myArray = ["Bob", "Fred"];

let myStr: string = myArray[0]; //ok
//let myStr: string = myArray["0"]; //error

//TypeScript支持两种索引签名：字符串和数字。
// 可以同时使用两种类型的索引，但是数字索引的返回值必须是字符串索引返回值类型的子类型。
// 这是因为当使用 number来索引时，JavaScript会将它转换成string然后再去索引对象。
//  也就是说用 100（一个number）去索引等同于使用"100"（一个string）去索引，因此两者需要保持一致。

//类类型
//实现接口
// 类静态部分与实例部分的区别;
interface ClockInterface {
    currentTime: Date;
}
interface ClockContructor {
    //构造函数属于类的静态部分
    new (hour: number, minute: number): ClockInterface;
}
function createClock(ctor: ClockContructor, hour: number, minute: number): ClockInterface {
    return new ctor(hour, minute);
}
class DigitalClock implements ClockInterface {
    currentTime: Date = new Date();
}

//继承接口
interface Shape {
    color: string;
}

interface PenStroke {
    penWidth: number;
}

interface Square extends Shape, PenStroke {
    sideLength: number;
}

let square: Square = {
    color: "blue",
    penWidth: 5.0,
    sideLength: 10,
};

//混合类型
interface Counter {
    (start: number): string;
    interval: number;
    reset(): void;
}
function getCounter(): Counter {
    let counter = function (start: number) {} as Counter;
    counter.interval = 123;
    counter.reset = function () {};
    return counter;
}
